package com.ohos.elegantunderline;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.multimodalinput.event.TouchEvent;

/**
 * 下划线.
 */

public class UnderlineView extends Component implements Component.EstimateSizeListener,
    Component.DrawTask, Component.TouchEventListener {
  private static final String TAG = UnderlineView.class.getSimpleName();
  static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00201, TAG);
  private static final String ATTR_FAMILY = "attr_family";
  private static final String ATTR_TEXT = "attr_text";
  private static final String UNDER_LINE_TYPE = "underLineType";
  private static final String ATTR_TEXT_COLOR = "attr_text_color";
  private static final String ATTR_TEXT_SIZE = "attr_text_size";
  private static final String ATTR_UNDER_LINE_COLOR = "attr_under_line_color";
  private static final String ATTR_UNDER_LINE_SIZE = "attr_under_line_size";
  private String family = "Arial";
  private String text;
  private String underLineType;
  private Color textColor = Color.BLACK;
  private int textSize = 70;
  private Color underLineColor = Color.BLACK;
  private float underLineSize = 2;
  private Paint paint;
  private Path underline;
  private Paint underlinePaint;
  public int componentWidth = ComponentContainer.LayoutConfig.MATCH_PARENT;
  public int componentHeight = 200;

  /**
   * 构造方法.
   */

  public UnderlineView(Context context, AttrSet attrSet) {
    super(context, attrSet);
    if (attrSet == null) {
      return;
    }
    if (attrSet.getAttr(UNDER_LINE_TYPE).isPresent()) {
      underLineType = attrSet.getAttr(UNDER_LINE_TYPE).get().getStringValue();
    }
    if (attrSet.getAttr(ATTR_FAMILY).isPresent()) {
      family = attrSet.getAttr(ATTR_FAMILY).get().getStringValue();
    }
    if (attrSet.getAttr(ATTR_TEXT).isPresent()) {
      text = attrSet.getAttr(ATTR_TEXT).get().getStringValue();
    }
    if (attrSet.getAttr(ATTR_TEXT_COLOR).isPresent()) {
      textColor = attrSet.getAttr(ATTR_TEXT_COLOR).get().getColorValue();
    }
    if (attrSet.getAttr(ATTR_TEXT_SIZE).isPresent()) {
      textSize = attrSet.getAttr(ATTR_TEXT_SIZE).get().getIntegerValue();
    }
    if (attrSet.getAttr(ATTR_UNDER_LINE_COLOR).isPresent()) {
      underLineColor = attrSet.getAttr(ATTR_UNDER_LINE_COLOR).get().getColorValue();
    }
    if (attrSet.getAttr(ATTR_UNDER_LINE_SIZE).isPresent()) {
      underLineSize = attrSet.getAttr(ATTR_UNDER_LINE_SIZE).get().getFloatValue();
    }
    setTouchEventListener(this);
    initPaint();
    setEstimateSizeListener(this);
    addDrawTask(this);
  }


  @Override
  public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
    int widthSpce = EstimateSpec.getMode(widthEstimateConfig);
    int heightSpce = EstimateSpec.getMode(heightEstimateConfig);
    //UNCONSTRAINT 父组件对子组件没有约束，表示子组件可以任意大小。
    //PRECISE 父组件已确定子组件的大小。
    //NOT_EXCEED 已为子组件确定了最大大小，子组件不能超过指定大小。
    int widthConfig = 0;
    switch (widthSpce) {
      case EstimateSpec.UNCONSTRAINT:
      case EstimateSpec.PRECISE:
        componentWidth = EstimateSpec.getSize(widthEstimateConfig);
        widthConfig = EstimateSpec.getSizeWithMode(componentWidth, EstimateSpec.PRECISE);
        break;
      case EstimateSpec.NOT_EXCEED:
        widthConfig = EstimateSpec.getSizeWithMode(componentWidth, EstimateSpec.PRECISE);
        break;
      default:
        break;
    }

    int heightConfig = 0;
    switch (heightSpce) {
      case EstimateSpec.UNCONSTRAINT:
      case EstimateSpec.PRECISE:
        componentHeight = EstimateSpec.getSize(heightEstimateConfig);
        heightConfig = EstimateSpec.getSizeWithMode(componentHeight, EstimateSpec.PRECISE);
        break;
      case EstimateSpec.NOT_EXCEED:
        heightConfig = EstimateSpec.getSizeWithMode(componentHeight, EstimateSpec.PRECISE);
        break;
      default:
        break;
    }
    System.out.println("WYT_width:" + componentWidth + "   height:" + heightConfig
        + "     width_spec:" + widthSpce + "     height_spec:" + heightSpce);
    setEstimatedSize(widthConfig, heightConfig);
    return true;
  }

  private void initPaint() {
    paint = new Paint();
    paint.getTextBounds(text);
    paint.setColor(textColor);
    paint.setTextSize(textSize);
    paint.setStyle(Paint.Style.FILL_STYLE);
    paint.setStrokeWidth(2f);
    Font.Builder builder = new Font.Builder(family);
    paint.setFont(builder.build());
    underlinePaint = new Paint();
    underlinePaint.setColor(underLineColor);
    if ("PATH".equals(underLineType)) {
      underlinePaint.setStrokeWidth(4f);
    } else {
      underlinePaint.setStrokeWidth(underLineSize);
    }
  }

  @Override
  public void onDraw(Component component, Canvas canvas) {
    Paint.FontMetrics fm = paint.getFontMetrics();
    float textHeight = fm.descent - fm.ascent;
    float textWidth = paint.measureText(text);
    canvas.translate(0f, (componentHeight - textHeight) / 2.0f + textHeight);
    canvas.drawText(paint, text, (componentWidth - textWidth) / 2.0f, 0f);
    if (null == text) {
      return;
    }
    String[] texts = text.split("[jgqyp]");
    float lastWidth = 0.0f;
    for (int i = 0; i < texts.length; i++) {
      float textsWidth = paint.measureText(texts[i]);
      underline = new Path();
      RectFloat rectB;
      if (0 != i && !text.contains("j")) {
        lastWidth = paint.measureText(texts[i - 1]);
        float charWidth = paint.measureText("g");
        canvas.translate(lastWidth + charWidth, 0.0f);
        rectB = new RectFloat(0.0f, 0.0f, textsWidth, underLineSize);
      } else {
        canvas.translate((componentWidth - textWidth) / 2.0f, 10.0f);
        rectB = new RectFloat(0.0f, 0.0f, textsWidth, underLineSize);
      }
      underline.addRect(rectB, Path.Direction.CLOCK_WISE);
      canvas.drawPath(underline, underlinePaint);
    }
  }

  @Override
  public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
    HiLog.info(LABEL_LOG, "onTouchEvent");
    return false;
  }
}
